package com.avhdeveloper.utils;

public class Assert {


  public static final String DEFAULT_NOT_NULL_MESSAGE = "value cannot be null";
  public static final String DEFAULT_TRUE_MESSAGE = "[Assertion failed] - this expression must be true";
  public static final String DEFAULT_FALSE_MESSAGE = "[Assertion failed] - this expression must be false";

  public static void notNull(Object obj) {
    notNull(obj, DEFAULT_NOT_NULL_MESSAGE);
  }

  public static void notNull(Object obj, String message) {
    if (message == null) {
      notNull(obj);
    }

    if (obj == null) {
      throw new IllegalArgumentException(message);
    }
  }

  /**
   * Assert that the provided object is an instance of the provided class. <pre class="code">Assert.instanceOf(Foo.class, foo);</pre>
   * @param clazz the required class
   * @param obj the object to check
   * @throws IllegalArgumentException if the object is not an instance of clazz
   * @see Class#isInstance
   */
  public static void isInstanceOf(Class clazz, Object obj) {
    isInstanceOf(clazz, obj, "");
  }

  /**
   * Assert that the provided object is an instance of the provided class. <pre class="code">Assert.instanceOf(Foo.class, foo);</pre>
   * @param type the type to check against
   * @param obj the object to check
   * @param message a message which will be prepended to the message produced by the function itself, and which may be used to provide context. It should
   *          normally end in a ": " or ". " so that the function generate message looks ok when prepended to it.
   * @throws IllegalArgumentException if the object is not an instance of clazz
   * @see Class#isInstance
   */
  public static void isInstanceOf(Class type, Object obj, String message) {
    notNull(type, "Type to check against must not be null");
    if (!type.isInstance(obj)) {
      throw new IllegalArgumentException(message + "Object of class [" + (obj != null ? obj.getClass().getName() : "null") + "] must be an instance of " + type);
    }
  }

  /**
   * Assert a boolean expression, throwing <code>IllegalArgumentException</code> if the test result is <code>false</code>. <pre class="code">Assert.isTrue(i
   * &gt; 0, "The value must be greater than zero");</pre>
   * @param expression a boolean expression
   * @param message the exception message to use if the assertion fails
   * @throws IllegalArgumentException if expression is <code>false</code>
   */
  public static void isTrue(boolean expression, String message) {
    if (!expression) {
      throw new IllegalArgumentException(message);
    }
  }

  /**
   * Assert a boolean expression, throwing <code>IllegalArgumentException</code> if the test result is <code>false</code>. <pre class="code">Assert.isTrue(i
   * &gt; 0);</pre>
   * @param expression a boolean expression
   * @throws IllegalArgumentException if expression is <code>false</code>
   */
  public static void isTrue(boolean expression) {
    isTrue(expression, DEFAULT_TRUE_MESSAGE);
  }

  /**
   * Assert a boolean expression, throwing <code>IllegalArgumentException</code> if the test result is <code>true</code>.
   * @param expression a boolean expression
   * @param message the exception message to use if the assertion fails
   * @throws IllegalArgumentException if expression is <code>false</code>
   */
  public static void isFalse(boolean expression, String message) {
    if (expression) {
      throw new IllegalArgumentException(message);
    }
  }

  /**
   * Assert a boolean expression, throwing <code>IllegalArgumentException</code> if the test result is <code>true</code>.
   * @param expression a boolean expression
   * @throws IllegalArgumentException if expression is <code>false</code>
   */
  public static void isFalse(boolean expression) {
    isFalse(expression, DEFAULT_FALSE_MESSAGE);
  }

}
